﻿/**************************************************************************
创建时间:	2020/6/28
作	  者:	张存
邮 	  箱:	zhangcunliang@126.com

Copyright (c) zhcun.cn

描	述：
记	录：
***************************************************************************/
using Org.BouncyCastle.Asn1.X509.Qualified;
using System;
using System.Collections.Generic;
using System.Text;
using ZhCun.DbCore;
using ZhCun.DbCore.BuildSQLText;
using ZhCun.DbCore.Cores;
using ZhCun.DbCore.Entitys;
using ZhCun.Utils;
using ZhCun.Utils.Helpers;
using ZhCun.WebUtils.Authorizes;
using ZhCun.WebUtils.Configs;

namespace ZhCun.WebUtils.DB
{
    public delegate void BeforeExec(Type entityType, ILoginSession loginSession, ISqlBuilder sqlBuilder, EmDbOperation opType);

    public class DBMain : DBContextDebug
    {
        #region 静态构造函数

        static DBMain()
        {
            EnumHelper.StringToEnum(CommonConfig.THIS.CoreDbType, out _DbType);
            _ConnStr = CommonConfig.THIS.CoreDbConnStr;
        }

        readonly static EmDbType _DbType;
        readonly static string _ConnStr;

        #endregion

        public DBMain()
            : this(_ConnStr)
        { }

        public DBMain(string connStr)
            : base(_DbType, connStr)
        { }

        public ILoginSession LoginSession { set; get; }

        public static event BeforeExec OnBeforeExec;

        public static event Action<BaseResult> OnResultFinish;

        const string FN_ADD_USER_ID = "AddUserId";
        const string FN_ADD_HOST = "AddHost";
        const string FN_LAST_USER_ID = "LastUserId";
        const string FN_LAST_HOST = "LastHost";
        //const string FN_LAST_TIME = "LastTime";
        const string P_PARAM_HOST = "Arg_LoginHost";
        const string P_PARAM_USER_ID = "Arg_LoginUserId";

        protected override void ResultFinish(BaseResult result)
        {
            //TODO: 这里可以记录sql执行日志
            //Console.WriteLine(result.SqlContent);
            OnResultFinish?.Invoke(result);
        }

        public ExecResult Insert<TEntity>(TEntity entity, bool autoId, bool autoUserId)
            where TEntity : EntityBase, new()
        {
            if (autoId)
            {
                var id = ReflectionHelper.GetPropertyValue<string>(entity, "Id");
                if (id.IsEmpty())
                {
                    id = GuidHelper.NewId();
                    ReflectionHelper.SetPropertyValue(entity, "Id", id);
                }
            }
            if (autoUserId)
            {
                ReflectionHelper.SetPropertyValue(entity, FN_ADD_USER_ID, LoginSession?.CurrUser?.UserId);
            }
            ReflectionHelper.SetPropertyValue(entity, FN_ADD_HOST, LoginSession.LoginHost);
            return base.Insert(entity);
        }

        public override ExecResult Insert<TEntity>(TEntity entity)
        {
            return Insert(entity, true, true);
        }

        protected override ExecResult UpdateBase<TEntity>(TEntity entity, Func<ISqlBuilder, string> whereFun)
        {
            ReflectionHelper.SetPropertyValue(entity, FN_LAST_HOST, LoginSession?.LoginHost);
            ReflectionHelper.SetPropertyValue(entity, FN_LAST_USER_ID, LoginSession?.CurrUser?.UserId);

            return base.UpdateBase(entity, whereFun);
        }

        public override ProcResult ExecProcedure<ProcEntity>(ProcEntity procObj)
        {
            ReflectionHelper.SetPropertyValue(procObj, P_PARAM_HOST, LoginSession?.LoginHost);
            ReflectionHelper.SetPropertyValue(procObj, P_PARAM_USER_ID, LoginSession?.CurrUser?.UserId);
            return base.ExecProcedure<ProcEntity>(procObj);
        }

        protected override void BeforeExecSqlBuilder<TEntity>(ISqlBuilder sqlBuilder, EmDbOperation opType)
        {
            OnBeforeExec?.Invoke(typeof(TEntity), LoginSession, sqlBuilder, opType);
        }
    }
}
